home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / scope / 151-175 / scopedisk168 / tinytools / pform / pform.asm < prev    next >
Assembly Source File  |  1995-03-19  |  5KB  |  233 lines

  1. ; Format input lines to standard output
  2.  
  3.        INCLUDE "/include/init.i"
  4.  
  5. ;      OPT     D+
  6.  
  7. ; Local Equs
  8.  
  9. FormatBufSize  EQU     1500
  10. MaxLineSize    EQU     512
  11. MaxFormatArgs  EQU     20
  12.  
  13. ; Variable storage
  14.  
  15.        STRUCT  ArgArray,(1+1)*4
  16.        STRUCT  ArgStream,MaxFormatArgs*4
  17.        STRUCT  FormatClipInfo,2*4
  18.        LONG    StdIn
  19.        LONG    StdOut
  20.        LONG    FormatBufPtr
  21.        SIZE
  22.  
  23. ; Regs
  24.  
  25. ByteFetch      EQUR    D4
  26. ReadBytesLeft  EQUR    D5
  27. LineBufPtr     EQUR    D6
  28. LineBufLeft    EQUR    D7
  29. LineEndPtr     EQUR    A2
  30. ErrorStrPtr    EQUR    A4
  31.  
  32. ; Startup
  33.  
  34.        STACK   4000
  35.        INIT
  36.  
  37. ; Let ARP interpret the commandline
  38.  
  39.        MOVE.L  ComLineBase(GP),A0
  40.        MOVE.L  ComLineSize(GP),D0
  41.        LEA     HelpMsg(PC),A1
  42.        LEA     ArgArray(GP),A2
  43.        LEA     Template(PC),A3
  44.        MOVE.L  A1,(A2)
  45.        CALL    GADS
  46.        MOVE.L  (A2),ErrorStrPtr
  47.        TST.L   D0
  48.        BEQ     ErrorExit
  49.        BMI     ErrorExit
  50.  
  51. ; Open the standard input & output
  52.  
  53.        CALL    Input
  54.        MOVE.L  D0,StdIn(GP)
  55.        CALL    Output
  56.        MOVE.L  D0,StdOut(GP)
  57.  
  58. ; Alloc tracked mem for the string format buffer.
  59.  
  60.        LEA     OutOfMem(PC),ErrorStrPtr
  61.        MOVE.L  #FormatBufSize,D0
  62.        MOVEQ   #0,D1
  63.        CALL    ArpAllocMem
  64.        MOVE.L  D0,FormatBufPtr(GP)
  65.        BEQ     ErrorExit
  66.  
  67. ; Allocate the read-line buffer
  68.  
  69.        MOVE.L  #MaxLineSize+4+MaxLineSize,D0   ; 2 part buf with 0 term space.
  70.        MOVEQ   #0,D1
  71.        CALL    ArpAllocMem
  72.        MOVE.L  D0,LineBufPtr
  73.        BEQ     ErrorExit
  74.  
  75. ; Initialize the argument stream
  76.  
  77.        MOVEQ   #MaxFormatArgs-1,D0
  78.        LEA     ArgStream(GP),A0
  79. InitArgStreamLongs:
  80.        MOVE.L  LineBufPtr,(A0)+
  81.        DBRA    D0,InitArgStreamLongs
  82.  
  83.  
  84. ; ** This is an intelligent ReadLine routine.
  85.  
  86.        MOVEQ   #0,ReadBytesLeft
  87.  
  88. ; Reinitialize the line buffer. (First part of dual buffer space)
  89.  
  90. DoForEachLine:
  91.        LEA     ReadError(PC),ErrorStrPtr
  92.        MOVE.L  LineBufPtr,LineEndPtr
  93.        MOVE.L  #MaxLineSize,LineBufLeft
  94.  
  95. ; Extract lines from the readbuffer into the line buffer.
  96.  
  97.        BRA.S   ExtractEntry
  98. CopyLineBytes:
  99.        MOVE.L  ByteFetch,A0
  100.        ADDQ.L  #1,ByteFetch
  101.        SUBQ.L  #1,ReadBytesLeft
  102.        MOVE.B  (A0),D0
  103.        CMP.B   #10,D0
  104.        BEQ.S   GotLine
  105.        MOVE.B  D0,(LineEndPtr)+
  106.        SUBQ.L  #1,LineBufLeft
  107.        BEQ.S   GotLine
  108. ExtractEntry:
  109.        TST.L   ReadBytesLeft
  110.        BNE     CopyLineBytes
  111.  
  112. ; Refill the read buffer.
  113.  
  114.        MOVE.L  StdIn(GP),D1
  115.        MOVE.L  LineBufPtr,D2
  116.        MOVE.L  #MaxLineSize,D3
  117.        ADD.L   D3,D2
  118.        ADDQ.L  #4,D2
  119.        CALL    Read
  120.        TST.L   D0
  121.        BMI.S   ErrorExit
  122.        BNE.S   NotYetDone
  123.        CMP.L   LineBufPtr,LineEndPtr
  124.        BEQ.S   Exit
  125. NotYetDone:
  126.        MOVE.L  D2,ByteFetch
  127.        MOVE.L  D0,ReadBytesLeft
  128.        BNE     CopyLineBytes
  129.  
  130. ; Null terminate the line.
  131.  
  132. GotLine:
  133.        CLR.B   (LineEndPtr)
  134.  
  135. ; Format things, terminate with a LF, and write the format buffer
  136.  
  137.        BSR.S   VanillaDoFmt
  138.        MOVE.L  FormatBufPtr(GP),A0
  139.        MOVE.B  #10,-1(A0,D0.L)
  140.  
  141.        LEA     WriteError(PC),ErrorStrPtr
  142.        MOVE.L  StdOut(GP),D1
  143.        MOVE.L  A0,D2
  144.        MOVE.L  D0,D3
  145.        BEQ.S   WriteDone
  146.        CALL    Write
  147.        CMP.L   D0,D3
  148.        BNE.S   ErrorExit
  149. WriteDone:
  150.  
  151. ; Check if user hit ^C 
  152.  
  153.        SUB.L   A1,A1
  154.        CALL    CheckAbort
  155.        MOVE.L  A1,ErrorStrPtr
  156.        TST.L   D0
  157.        BNE.S   ErrorExit
  158.        BRA     DoForEachLine
  159.  
  160. ; Done, cleanup
  161.  
  162. Exit:
  163.        CLR.W   ReturnCode(GP)
  164.        SUB.L   ErrorStrPtr,ErrorStrPtr
  165. ErrorExit:
  166.  
  167. ; Display error string, if any, and exit
  168.  
  169.        MOVE.L  ErrorStrPtr,D0
  170.        BEQ.S   NoErrorMsg
  171.        MOVE.L  D0,A1
  172.        CALL    Puts
  173. NoErrorMsg:
  174.        RTS
  175.  
  176. ; Subroutines
  177.  
  178. ; This sub uses exec's RawDoFmt to do string formatting while clipping
  179. ; any surplus data to fit the buffer size. Arps format routines have
  180. ; no overflow checks, and since the user is not guaranteed to act
  181. ; sanely, clipping is essential.
  182. ; I : Assumes a valid format string and buffer
  183. ; O : The format buffer contain the formatted string.
  184. ;   : D0.L = Size of formatted string.
  185.  
  186. Vanilla_Regs   REG     A2/A3/A6
  187.  
  188. VanillaDoFmt:
  189.        MOVEM.L Vanilla_Regs,-(SP)
  190.        MOVE.L  ArgArray(GP),A0
  191.        LEA     ArgStream(GP),A1
  192.        LEA     DoClippedBufferFill(PC),A2
  193.        LEA     FormatClipInfo(GP),A3
  194.        MOVE.L  FormatBufPtr(GP),(A3)
  195.        MOVE.L  (A3),4(A3)
  196.        ADD.L   #FormatBufSize,4(A3)
  197.        MOVE.L  $4.W,A6                         ; exec
  198.        CALL    RawDoFmt
  199.        MOVE.L  (A3),D0
  200.        SUB.L   FormatBufPtr(GP),D0
  201.        MOVEM.L (SP)+,Vanilla_Regs
  202.        RTS
  203.  
  204. ; Assumes A0 is usable, not clear from autodocs whether this is true.
  205. ; (Default calling conventions and ROM code suggest it is)
  206.  
  207. DoClippedBufferFill:
  208.        MOVE.L  (A3)+,A0
  209.        CMP.L   (A3),A0
  210.        BNE.S   NotYetAtBufEnd
  211.        SUBQ.L  #1,A0
  212. NotYetAtBufEnd:
  213.        MOVE.B  D0,(A0)+
  214.        MOVE.L  A0,-(A3)
  215.        RTS
  216.  
  217. ; The string section
  218.  
  219. Template:
  220.        DC.B    'FormatString/a',0
  221. HelpMsg:
  222.        DC.B    'PForm - Pipe formatted lines.',10
  223.        DC.B    'Usage: PForm "prefix %[width.limit]s postfix"',0
  224. OutOfMem:
  225.        DC.B    'Out of memory!',0
  226. ReadError:
  227.        DC.B    'Error while reading',0
  228. WriteError:
  229.        DC.B    'Error while writing',0
  230.        CNOP    0,2
  231.  
  232.        END
  233.